package com.kexilo.core.common.core.web.domain;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

import java.io.Serializable;
import java.util.Map;

/**
 * 错误响应模型
 * 
 * @author Kexilo
 */
@Data
@Schema(description = "错误响应对象")
public class ErrorResponse implements Serializable {
    
    private static final long serialVersionUID = 1L;

    @Schema(description = "错误码", example = "400")
    private int code;

    @Schema(description = "错误消息", example = "参数验证失败")
    private String message;

    @Schema(description = "错误详情", example = "用户名不能为空")
    private String detail;

    @Schema(description = "错误路径", example = "/api/system/user")
    private String path;

    @Schema(description = "错误时间戳", example = "1640995200000")
    private long timestamp;

    @Schema(description = "请求ID", example = "req_123456789")
    private String requestId;

    @Schema(description = "错误类型", example = "VALIDATION_ERROR")
    private String errorType;

    @Schema(description = "字段错误详情")
    private Map<String, String> fieldErrors;

    @Schema(description = "建议解决方案", example = "请检查输入参数")
    private String suggestion;

    public ErrorResponse() {
        this.timestamp = System.currentTimeMillis();
    }

    public ErrorResponse(int code, String message) {
        this();
        this.code = code;
        this.message = message;
    }

    public ErrorResponse(int code, String message, String detail) {
        this(code, message);
        this.detail = detail;
    }

    /**
     * 参数验证错误
     */
    public static ErrorResponse validationError(String message) {
        ErrorResponse error = new ErrorResponse(400, message);
        error.setErrorType("VALIDATION_ERROR");
        error.setSuggestion("请检查输入参数格式和内容");
        return error;
    }

    /**
     * 参数验证错误（带字段错误）
     */
    public static ErrorResponse validationError(String message, Map<String, String> fieldErrors) {
        ErrorResponse error = validationError(message);
        error.setFieldErrors(fieldErrors);
        return error;
    }

    /**
     * 业务逻辑错误
     */
    public static ErrorResponse businessError(String message) {
        ErrorResponse error = new ErrorResponse(400, message);
        error.setErrorType("BUSINESS_ERROR");
        error.setSuggestion("请检查业务逻辑和数据状态");
        return error;
    }

    /**
     * 认证失败错误
     */
    public static ErrorResponse authenticationError() {
        ErrorResponse error = new ErrorResponse(401, "认证失败");
        error.setErrorType("AUTHENTICATION_ERROR");
        error.setSuggestion("请重新登录或检查认证token");
        return error;
    }

    /**
     * 权限不足错误
     */
    public static ErrorResponse authorizationError() {
        ErrorResponse error = new ErrorResponse(403, "权限不足");
        error.setErrorType("AUTHORIZATION_ERROR");
        error.setSuggestion("请联系管理员获取相应权限");
        return error;
    }

    /**
     * 资源不存在错误
     */
    public static ErrorResponse notFoundError(String resource) {
        ErrorResponse error = new ErrorResponse(404, "资源不存在");
        error.setDetail(resource + "不存在或已被删除");
        error.setErrorType("RESOURCE_NOT_FOUND");
        error.setSuggestion("请检查资源ID或刷新页面重试");
        return error;
    }

    /**
     * 请求方法不支持错误
     */
    public static ErrorResponse methodNotAllowedError(String method) {
        ErrorResponse error = new ErrorResponse(405, "请求方法不支持");
        error.setDetail("不支持" + method + "请求方法");
        error.setErrorType("METHOD_NOT_ALLOWED");
        error.setSuggestion("请检查API文档使用正确的请求方法");
        return error;
    }

    /**
     * 媒体类型不支持错误
     */
    public static ErrorResponse unsupportedMediaTypeError() {
        ErrorResponse error = new ErrorResponse(415, "媒体类型不支持");
        error.setErrorType("UNSUPPORTED_MEDIA_TYPE");
        error.setSuggestion("请使用application/json格式发送请求");
        return error;
    }

    /**
     * 请求过于频繁错误
     */
    public static ErrorResponse tooManyRequestsError() {
        ErrorResponse error = new ErrorResponse(429, "请求过于频繁");
        error.setErrorType("TOO_MANY_REQUESTS");
        error.setSuggestion("请稍后再试或联系管理员调整限流配置");
        return error;
    }

    /**
     * 服务器内部错误
     */
    public static ErrorResponse internalServerError() {
        ErrorResponse error = new ErrorResponse(500, "服务器内部错误");
        error.setErrorType("INTERNAL_SERVER_ERROR");
        error.setSuggestion("请联系技术支持或稍后重试");
        return error;
    }

    /**
     * 服务不可用错误
     */
    public static ErrorResponse serviceUnavailableError() {
        ErrorResponse error = new ErrorResponse(503, "服务暂时不可用");
        error.setErrorType("SERVICE_UNAVAILABLE");
        error.setSuggestion("系统正在维护中，请稍后重试");
        return error;
    }

    /**
     * 设置请求路径
     */
    public ErrorResponse path(String path) {
        this.path = path;
        return this;
    }

    /**
     * 设置请求ID
     */
    public ErrorResponse requestId(String requestId) {
        this.requestId = requestId;
        return this;
    }

    /**
     * 设置详情
     */
    public ErrorResponse detail(String detail) {
        this.detail = detail;
        return this;
    }
}
